package util 
{
	import com.adobe.serialization.json.JSON;
	import flash.display.MovieClip;
	
	import flash.display.Loader;
	import flash.errors.EOFError;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	
	import org.osflash.signals.Signal;	
	
	/**
	 * ...
	 * @author Qi Donghui
	 */
	public class ElemLib
	{
		private static var _lib : Object = { };
		
		/**
		 * 所有形象动画
		 */
		private static var _role:Object = { };
		
		/**
		 * 所有的回调函数数组
		 * 包含的单个元素也是数组，是所有针对同一个元件回调函数的数组集合
		 */
		private static var _handlers : Array = [];
		
		/**
		 * 添加的所有元件的名称的数组
		 */
		private static var _names : Array = [];
		
		/**
		 * 所有的URLStream的应用数组
		 */
		private static var _uss : Array = [];	
		
		/**
		 * 发生错误时的回调函数
		 */
		private static var _errors:Array = [];		
		
		public static var instance:ElemLib;
		
		public static var allowInstance:Boolean;		
		
		public function ElemLib() 
		{
			if (!allowInstance)
			{
				throw new Error("Error: use ElemLib.getInstance() instead of new keyword");
			}
		}
		
		/**
		 * 单例模式获取实例的方法
		 * @return
		 */
		public static function getInstance():ElemLib
		{
			if (instance == null) {
				allowInstance = true;
				instance = new ElemLib();
				allowInstance = false;
			}
			return instance;
		}
		
		/**
		 * 从外部加载元素到元素库
		 * @param url 元素路径
		 * @param name 要添加的名称
		 * @param handler 添加后的处理函数
		 */
		public function addElem(url : String, name : String, handler : Function = null, errorHandler:Function = null) : void 
		{
			if (_lib[name]) 
			{
				if(handler != null) handler(); 
				return;
			}
			
			var n : int = _names.indexOf(name);
			if (n >= 0)
			{
				///此时说明已经有相同的东西虽然还没在_lib里面，但是已经是处在加载阶段了
				_handlers[n].push(handler);
				return;
			}
			
			_handlers.push([handler]);
			_names.push(name);
			_errors.push(errorHandler);			
			
			var us : URLStream = new URLStream();
			_uss.push(us);
			us.addEventListener(Event.COMPLETE, streamCompHandler);
			us.addEventListener(IOErrorEvent.IO_ERROR, streamIOErrorHandler);
			us.load(new URLRequest(url));
		}
		
		/**
		 * 以2进制数的形式去添加单个元素
		 * @param	evt
		 */
		private function streamCompHandler(evt : Event) : void 
		{
			var us : URLStream = evt.target as URLStream;
			var ba : ByteArray = new ByteArray();
			
			var n : int = _uss.indexOf(us);
			var name : String = _names[n];
			//var handler : Function = _handlers[n];
			var arrHandler :Array = _handlers[n];			
			
			try {
				us.readBytes(ba);				
				if (ba.length > 0) _lib[name] = ba;
				//trace("readbytes::::" + name);
			}catch (eofErr:EOFError) {
				//trace("*******************************************EOFError");
			}catch (ioErr:IOError) {
				//trace("*******************************************IOError");
			}			
			
			if (arrHandler != null)
			{
				for (var i:int = 0, len:int = arrHandler.length; i < len ; i ++)
				{
					var handler:Function = arrHandler[i];
					if(handler != null) handler();
				}
			}
			
			us.removeEventListener(Event.COMPLETE, streamCompHandler);
			us.removeEventListener(IOErrorEvent.IO_ERROR, streamIOErrorHandler);
			
			_uss.splice(n, 1);
			_names.splice(n, 1);
			_handlers.splice(n, 1);
			_errors.splice(n, 1);
		}
		
		private static function streamIOErrorHandler(evt : IOErrorEvent):void
		{
			var us : URLStream = evt.target as URLStream;
			
			var n : int = _uss.indexOf(us);
			var error:Function = _errors[n];
			if (error != null ) error();
			
			_uss.splice(n, 1);
			_names.splice(n, 1);
			_handlers.splice(n, 1);
			_errors.splice(n, 1);
		}
		
		/**
		 * 通过名称获取元素
		 * @param name 名称
		 * @return 返回值为MovieClip或ByteArray或null
		 */
		public function getElemByName(name : String) : Object 
		{
			return _lib[name];
		}		
		
	}

}